package concurrent;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.*;

/**
 * 应用模块名称<p> 客户端类型
 * 代码描述<p>
 * copyright:
 * Company: 上海悟泰信息科技有限公司
 *
 * @author jack.wu
 * @since 2019/12/31 16:47
 */
public class UnsafeDemo {

    private static Unsafe unsafe;
    /**
     * 计数器
     */
    private static int count;
    /**
     * 地址偏移量
     */
    private static long countOffset;

    static {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
            Field countField = UnsafeDemo.class.getDeclaredField("count");
            countOffset = unsafe.staticFieldOffset(countField);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 模拟访问请求
     *
     * @throws InterruptedException InterruptedException
     */
    private static void request() throws InterruptedException {
        TimeUnit.SECONDS.sleep(2);
        unsafe.getAndAddInt(UnsafeDemo.class, countOffset, 1);
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5,
                10,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(10),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        long startTime = System.currentTimeMillis();
        int threadSize = 10;
        CountDownLatch downLatch = new CountDownLatch(threadSize);
            executor.execute(() -> {
                for (int j = 0; j < 10; j++) {
                    try {
                        request();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        downLatch.countDown();
                    }
                }
            });

        downLatch.await();
        executor.shutdown();
        long endTime = System.currentTimeMillis();
        System.out.println("countOffset : " + countOffset);
        System.out.println(Thread.currentThread().getName() + "耗时：" + (endTime - startTime) + "，次数：" + count);
    }

}
